//
//  XUIPreviewImageViewController.m
//  Etion
//
//  Created by hua ouyang on 11-9-29.
//  Copyright 2011年 GuangZhouXuanWu. All rights reserved.
//

#import "XUIPreviewImageViewController.h"

#import "UIImageExtend.h"

#import "XMSFileHelper.h"

#import "XUIPreviewImageViewInternal.h"

#define MAX_THUMBNAIL_W 40
#define MAX_THUMBNAIL_H 40

typedef NS_ENUM(NSUInteger, XUIPreviewImageViewControllerPresentType)
{
    XUIPreviewImageViewControllerPresentTypeDefault,
    XUIPreviewImageViewControllerPresentTypeZoom
};

@interface XUIPreviewImageAtt : NSObject
{
    NSString *_originImagePath;
    UIImage *_image;
    UIImage *_thumbnail;
    CGSize _size;

    NSString *_thumbImagePath;
}

@property(nonatomic, retain) NSString *originImagePath;
@property(nonatomic, retain) UIImage *image;
@property(nonatomic, retain) UIImage *thumbnail;
@property(nonatomic, assign) CGSize size;
@property(nonatomic, retain) NSString *thumbImagePath;

@end

@implementation XUIPreviewImageAtt

- (void)dealloc
{
    [_image release_mm];
    [_originImagePath release_mm];
    [_thumbnail release_mm];
    [_thumbImagePath release_mm];
    superdealloc_mm;
}

@end

@interface XUIPreviewImageViewController () <XUIPreviewImageViewInternalDelegate, XMSSimpleDownloadManagerDelegate>
{
    XUIPreviewImageViewInternal *_viewBrowser;

    NSMutableArray *_previewImageAtts;

    BOOL _isHiddenNavigationBar;

    NSString *_savePath;

    BOOL _downloadImageIfNeed;

    BOOL _createThumbIfNeed;

    NSUInteger _defaultSelectIndex;

    XMSSimpleDownloadManager *_sdm;
    
    BOOL _rotationToInterfaceOrientation;
    
    XUIPreviewImageViewControllerPresentType _presentType;
    
    NSMutableArray *_imageContainViews;
    
    BOOL _hiddenStatusBar;
}

@property(nonatomic,strong) NSMutableArray *imageContainViews;

- (void)zoomDismissPreviewImageView:(BOOL)animated;

@end

@implementation XUIPreviewImageViewController

@synthesize rotationToInterfaceOrientation = _rotationToInterfaceOrientation;

@synthesize imageContainViews = _imageContainViews;

- (id)initWithImagePaths:(NSArray *)paths
{
    NSMutableArray *ar = [[NSMutableArray new] autorelease_mm];
    for (NSString *path in paths)
    {
        [ar addObject:[UIImage imageWithContentsOfFile:path]];
    }
    return [self initWithImages:ar];
}

- (id)initWithImages:(NSArray *)images
{
    self = [self init];
    
    if (images.count <= 0)
        return self;
    [self initPreviewImageAttsWithImages:images];
    
    return self;
}

- (id)init
{
    self = [super init];
    
    _hiddenStatusBar = NO;

    _rotationToInterfaceOrientation = YES;
    
    return self;
}

- (id)initWithThumbImagePath:(NSArray *)thumbImagePaths originImageURL:(NSArray *)originImageURLs downloadSavePath:(NSString *)savePath
{
    self = [self init];

    _downloadImageIfNeed = YES;

    [self initPreviewImageAttsWithThumbImageURL:thumbImagePaths originImageURL:originImageURLs downloadSavePath:savePath];

    return self;
}

- (id)initWithImageURL:(NSArray *)originImageURLs downloadSavePath:(NSString *)savePath
{
    self = [self init];

    return self;
}

- (void)dealloc
{
    [_imageContainViews release_mm];
    [_sdm release_mm];
    [_viewBrowser release_mm];
    [_previewImageAtts release_mm];
    [_savePath release_mm];
    superdealloc_mm;
}

- (void)presentViewControllerWithAnimated:(BOOL)animated completion:(void (^)())completion
{
    [[UIViewController currentRootViewController] presentViewController:self animated:animated completion:^
    {
        self.view.superview.backgroundColor = [UIColor blackColor];
        completion();
    }];
}

- (void)presentViewControllerCompletion:(void (^)())completion
{
    [self presentViewControllerWithAnimated:YES completion:completion];
}

- (void)dismissViewController:(BOOL)animated completion:(void (^)())completion
{
    if(_presentType == XUIPreviewImageViewControllerPresentTypeDefault )
        [[UIViewController currentRootViewController] dismissViewControllerAnimated:animated completion:completion];
    else
        [self zoomDismissPreviewImageView:animated];
}

- (void)zoomDismissPreviewImageView:(BOOL)animated
{
    
}

#pragma mark - deal preview image atts

- (void)updatePreviewImageAtt:(XUIPreviewImageAtt *)att
{
    if (att.thumbImagePath.length > 0)
    {
        UIImage *thumbImage = nil;
        if ([XMSFileHelper isFileExist:att.thumbImagePath])
            thumbImage = [UIImage imageWithContentsOfFile:att.thumbImagePath];
        else
            thumbImage = [UIImage imageNamed:@"image_default.png"];

        att.thumbnail = thumbImage;
        att.size = att.thumbnail.size;
    }
    else if (att.originImagePath.length > 0)
    {
        UIImage *image = nil;
        if ([XMSFileHelper isFileExist:att.originImagePath])
        {
            image = [UIImage imageWithContentsOfFile:att.originImagePath];
            att.thumbnail = [UIImage imageFromImage:image scaledToFitSize:CGSizeMake(MAX(MAX_THUMBNAIL_W, image.size.width / 4), MAX(MAX_THUMBNAIL_H, image.size.height / 4))];
            att.size = att.thumbnail.size;
        }
        else
        {
            image = [UIImage imageNamed:@"image_default.png"];
            att.image = image;
            att.size = att.image.size;
        }
    }
}

- (void)initPreviewImageAttsWithThumbImageURL:(NSArray *)thumbImageURLs originImageURL:(NSArray *)originImageURLs downloadSavePath:(NSString *)savePath
{
    _savePath = [savePath retain_mm];

    _previewImageAtts = [NSMutableArray new];

    for (NSUInteger i = 0; i < thumbImageURLs.count; i++)
    {
        NSString *thumbImageURL = thumbImageURLs[i];

        XUIPreviewImageAtt *att = [[XUIPreviewImageAtt new] autorelease_mm];
        [_previewImageAtts addObject:att];

        att.thumbImagePath = thumbImageURL;
        if (originImageURLs.count > 0 && i < originImageURLs.count)
            att.originImagePath = originImageURLs[i];

        [self updatePreviewImageAtt:att];
    }
}

- (void)initPreviewImageAttsWithPaths:(NSArray *)arImagePaths
{
    _previewImageAtts = [NSMutableArray new];
    for (NSString *szPath in arImagePaths)
    {
        XUIPreviewImageAtt *att = [[XUIPreviewImageAtt new] autorelease_mm];
        [_previewImageAtts addObject:att];

        att.originImagePath = szPath;

        [self updatePreviewImageAtt:att];
    }
}

- (void)initPreviewImageAttsWithImages:(NSArray *)arImages
{
    _previewImageAtts = [NSMutableArray new];
    for (UIImage *image in arImages)
    {
        XUIPreviewImageAtt *att = [[XUIPreviewImageAtt new] autorelease_mm];
        [_previewImageAtts addObject:att];

        att.image = image;
        att.size = att.image.size;
    }
}

#pragma mark -

- (void)viewDidLoad
{
    [self initViewDidLoad];
}

- (void)initViewDidLoad
{
    self.view.clipsToBounds = YES;

    [self createNavBar];

    self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;

    self.view.backgroundColor = [UIColor blackColor];

    _navBar.alpha = 0.8;
    
    [self hiddenNavBar:YES animated:NO];
    
//    [self setNeedsStatusBarAppearanceUpdate];
    
    _viewBrowser = [[XUIPreviewImageViewInternal alloc] initWithFrame:CGRectMake(0, 0, self.view.width, self.view.height)];
    _viewBrowser.delegate = self;
    _viewBrowser.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    [self.view insertSubview:_viewBrowser belowSubview:_navBar];
    [_viewBrowser reloadView];

    [_viewBrowser selectCellAtIndex:_defaultSelectIndex];
    
    if(_rotationToInterfaceOrientation == YES)
    {
        [self addMainThreadObserverWithDictionarySelector:@{UIDeviceOrientationDidChangeNotification:@"observerUIDeviceOrientationDidChangeNotification:"}];
        DispatchMainThreadAsync(^
        {
            [self rotationInterfaceOrientation:NO];
        });
    }
}

- (void)observerUIDeviceOrientationDidChangeNotification:(NSNotification*)noti
{
    [self rotationInterfaceOrientation:YES];
}

- (void)rotationInterfaceOrientation:(BOOL)animated
{
    void(^fun)()=^
    {
        CGRect f = self.view.frame;
        
        UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
        
        if(orientation == UIDeviceOrientationLandscapeRight)
            self.view.transform = CGAffineTransformMakeRotation(-M_PI_2);
        else if(orientation == UIDeviceOrientationLandscapeLeft)
            self.view.transform = CGAffineTransformMakeRotation(M_PI_2);
        else if(orientation == UIDeviceOrientationPortraitUpsideDown)
            self.view.transform = CGAffineTransformMakeRotation(M_PI);
        else
            self.view.transform = CGAffineTransformIdentity;
    
        self.view.frame = f;

        [self rotationToInterfaceOrientation:orientation duration:0.25];
    };
    
    if(animated == YES)
    {
        [UIView animateWithDuration:0.25 animations:^
        {
            fun();
        }];
    }
    else
        fun();
}

- (void)createNavBar
{
    _navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, self.view.width, 49)];
    UINavigationItem *topItem = [[[UINavigationItem alloc]initWithTitle:@"图片查看"] autorelease_mm];
    topItem.hidesBackButton = YES;
    UIBarButtonItem *leftItem = [[[UIBarButtonItem alloc] initWithTitle:@"关闭" style:UIBarButtonItemStylePlain target:self action:@selector(clickedBackBarButton:)] autorelease_mm];
    topItem.leftBarButtonItem = leftItem;
    _navBar.items = @[topItem];
    [self.view addSubview:_navBar];
}

- (void)clickedBackBarButton:(id)sender
{
    [self dismissPreviewImageViewController:YES];
}

- (void)dismissPreviewImageViewController:(BOOL)animated
{
    [self removeObserver];
    
    [_sdm cancelAllDownloadTask];

    [self dismissViewController:animated completion:NULL];
}

- (void)hiddenNavBar:(BOOL)hidden animated:(BOOL)animated
{
    if (_isHiddenNavigationBar == hidden)
        return;

    void(^fun)() = ^
    {
        _isHiddenNavigationBar = hidden;

        if (_isHiddenNavigationBar)
        {
            _navBar.bottom = self.view.top;
        }
        else
        {
            _navBar.top = 0;
        }
    };
    if (animated == YES)
    {
        self.view.userInteractionEnabled = NO;

        [UIView animateWithDuration:0.25 animations:^
        {
            fun();
        } completion:^(BOOL finished)
        {
            self.view.userInteractionEnabled = YES;
        }];
    }
    else
        fun();
}

- (void)simpleDownloadManager:(XMSSimpleDownloadManager *)sdm willStartDownload:(CSimpleDownloadTaskTag *)tag
{
    DispatchMainThreadAsync(^
    {
        NSInteger index = [tag.attachment integerValue];
        [_viewBrowser enableActivityIndicatorAtIndex:index];
    });
}

- (void)simpleDownloadManager:(XMSSimpleDownloadManager *)sdm finishedDownload:(CSimpleDownloadTaskTag *)tag
{
    DispatchMainThreadAsync(^
    {
        NSInteger index = [tag.attachment integerValue];
        NSString *szImagePath = tag.filePath;
        XUIPreviewImageAtt *att = [_previewImageAtts objectAtIndex:index];
        [_viewBrowser disableActivityIndicatorAtIndex:index];
        if (_viewBrowser.currentIndex == index)
        {
            att.image = [UIImage imageWithContentsOfFile:szImagePath];
            att.size = att.image.size;
            [_viewBrowser updateCellAtIndex:index withImage:att.image originalSize:att.size animated:YES];
        }
        else
        {
            //    [m_viewBrowser updateCellAt:index withImage:att.m_thumbnail originalSize:att.m_size];
        }

        [self previewImageViewControllerFinishDownloadImage:szImagePath atIndex:index];
    });
}

-(void)simpleDownloadManager:(XMSSimpleDownloadManager *)sdm tag:(CSimpleDownloadTaskTag *)tag error:(NSError *)error
{
    DispatchMainThreadAsync(^
    {
        NSInteger index = [tag.attachment integerValue];
        [_viewBrowser disableActivityIndicatorAtIndex:index];
    });
}

- (void)previewImageViewControllerFinishDownloadImage:(NSString *)imageFilePath atIndex:(NSUInteger)index
{

}

- (BOOL)closePreviewImageViewControllerWhenClickPreviewImage
{
    return YES;
}

- (void)navBarSlidingAppearWhenClickPreviewImage:(BOOL)appear
{
}

- (BOOL)prefersStatusBarHidden
{
    return _hiddenStatusBar;
}

- (void)hiddenStatusBar:(BOOL)hidden
{
    if(_hiddenStatusBar == hidden)
        return;
    
    _hiddenStatusBar = hidden;
    
    [self setNeedsStatusBarAppearanceUpdate];
}

#pragma mark - Autorotate

/*
- (BOOL)shouldAutorotate
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}
*/

- (void)rotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    _navBar.width = UIInterfaceOrientationIsLandscape(toInterfaceOrientation) ? self.view.height : self.view.width;
    
    [_viewBrowser resetViewContentLocation:toInterfaceOrientation];
    
    [self previewImageViewControllerWillAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

/*
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    //对于ios7及以下系统，这时整个系统还没有旋转

    [self rotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

#ifdef __IPHONE_8_0
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    //对于ios8及以后系统，这时系统已经旋转，但当前界面还没有旋转
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
    {
        UIInterfaceOrientation toInterfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
        
        [_viewBrowser resetViewContentLocation:toInterfaceOrientation];
        
        [self rotationToInterfaceOrientation:toInterfaceOrientation duration:coordinator.transitionDuration];
        
    } completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
    {

    }];
    [super viewWillTransitionToSize: size withTransitionCoordinator: coordinator];
}
#endif

*/

- (void)previewImageViewControllerWillAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{

}

#pragma mark - XUIPreviewImageViewInternalDelegate

- (NSInteger)numberOfViews:(XUIPreviewImageViewInternal *)previewImageViewInternal
{
    return _previewImageAtts.count;
}

- (XUIPreviewImageViewInternalCell *)previewImageViewInternal:(XUIPreviewImageViewInternal *)previewImageViewInternal cellViewAtIndex:(NSUInteger)index
{
    XUIPreviewImageViewInternalCell *cell = [[[XUIPreviewImageViewInternalCell alloc] initWithBrowserStyle:EViewBrowserStyleCellDefault reuseIdentifier:@"viewBroserCell"] autorelease_mm];

    XUIPreviewImageAtt *att = [_previewImageAtts objectAtIndex:index];
    cell.imageOriginalSize = att.size;
    if (att.image != nil)
    {
        cell.imageView.image = att.image;
    }
    else if (att.thumbnail != nil)
    {
        cell.imageView.image = att.thumbnail;
    }
    else
    {
        cell.imageView.image = [UIImage imageNamed:@"image_default.png"];
    }

//    if ([att.originImagePath isEqualToString:@"image_default.png"] == YES)
//    {
//        [cell enableActivityIndicator];
//	}

    return cell;
}

- (void)previewImageViewInternal:(XUIPreviewImageViewInternal *)previewImageViewInternal clickViewAtIndex:(NSUInteger)index
{
    if (![self closePreviewImageViewControllerWhenClickPreviewImage])
    {
        _isHiddenNavigationBar = !_isHiddenNavigationBar;

        self.view.userInteractionEnabled = NO;

        [UIView animateWithDuration:0.5 animations:^
        {
        //    [self setNeedsStatusBarAppearanceUpdate];

            if (_isHiddenNavigationBar)
            {
                _navBar.bottom = self.view.top;
            }
            else
            {
                _navBar.top = 0;
            }

            [self navBarSlidingAppearWhenClickPreviewImage:!_isHiddenNavigationBar];

        }                completion:^(BOOL finished)
        {
            self.view.userInteractionEnabled = YES;
        }];
    }
    else
    {
        [self clickedBackBarButton:nil];
    }
}

- (void)previewImageViewInternal:(XUIPreviewImageViewInternal *)previewImageViewInternal didShowViewAtIndex:(NSUInteger)index
{
    XUIPreviewImageAtt *att = [_previewImageAtts objectAtIndex:index];
    if (att.image != nil)
    {
        att.size = att.image.size;
        [_viewBrowser updateCellAtIndex:index withImage:att.image originalSize:att.size animated:NO];

        [self didShowImageAtIndex:index andIsOriginalImage:YES];
    }
    else if (att.originImagePath.length > 0)
    {
        if (_downloadImageIfNeed == NO && [XMSFileHelper isFileExist:att.originImagePath] == YES)
        {
            UIImage *image = [UIImage imageWithContentsOfFile:att.originImagePath];
            if(image.size.height > 0.0 && image.size.width > 0.0)
            {
                att.image = image;
                att.size = att.image.size;
                [_viewBrowser updateCellAtIndex:index withImage:att.image originalSize:att.size animated:YES];

                [self didShowImageAtIndex:index andIsOriginalImage:YES];
            }
            else
            {
                [self didShowImageAtIndex:index andIsOriginalImage:NO];
            }
        }
        else if (_downloadImageIfNeed == YES)
        {
            NSString *path = [_savePath stringByAppendingPathComponent:[att.originImagePath lastPathComponent]];
            if ([XMSFileHelper isFileExist:path] == YES)
            {
                UIImage *image = [UIImage imageWithContentsOfFile:path];
                if(image.size.height > 0.0 && image.size.width > 0.0)
                {
                    att.image = image;
                    att.size = att.image.size;
                    
                    [_viewBrowser updateCellAtIndex:index withImage:att.image originalSize:att.size animated:YES];
                    
                    [self didShowImageAtIndex:index andIsOriginalImage:YES];
                }
                else
                {
                    [XMSFileHelper deleteFileDir:path];
                    
                    if (_sdm == nil)
                        _sdm = [[XMSSimpleDownloadManager alloc] initWithDelegate:self];
                    
                    [_sdm addDownloadTask:att.originImagePath path:path attachment:[NSNumber numberWithInteger:index]];
                    
                    [self didShowImageAtIndex:index andIsOriginalImage:NO];
                }
            }
            else
            {
                if (_sdm == nil)
                    _sdm = [[XMSSimpleDownloadManager alloc] initWithDelegate:self];

                if ([_sdm isContainDownloadURL:att.originImagePath] != YES)
                    [_sdm addDownloadTask:att.originImagePath path:path attachment:[NSNumber numberWithInteger:index]];

                [self didShowImageAtIndex:index andIsOriginalImage:NO];
            }
        }
    }
}

- (void)previewImageViewInternal:(XUIPreviewImageViewInternal *)previewImageViewInternal didHideViewAtIndex:(NSUInteger)index
{
    XUIPreviewImageAtt *att = [_previewImageAtts objectAtIndex:index];

    if (att.thumbnail != nil)
    {
        att.image = nil;
        att.size = att.thumbnail.size;
        [_viewBrowser updateCellAtIndex:index withImage:att.thumbnail originalSize:att.size animated:NO];
    }
    else
        [_viewBrowser updateCellAtIndex:index withImage:att.image originalSize:att.size animated:NO];
}

- (void)previewImageViewInternal:(XUIPreviewImageViewInternal *)previewImageViewInternal didScrollToNewIndex:(NSUInteger)newIndex
{
    [self didScrollToNewImageAtIndex:newIndex];
}

#pragma mark -------

- (void)deleteImageAtIndex:(NSUInteger)index
{
    [_previewImageAtts removeObjectAtIndex:index];
    [_viewBrowser deleteCellAtIndex:index];
}

- (void)deleteCurrentImage
{
    [self deleteImageAtIndex:_viewBrowser.currentIndex];
}

- (void)defaultSelectAtIndex:(NSUInteger)index
{
    _defaultSelectIndex = index;
}

- (NSUInteger)currentIndex
{
    return _viewBrowser.currentIndex;
}

- (NSUInteger)currentImageCount
{
    return _previewImageAtts.count;
}

- (UIImage *)currentOriginalImage
{
    XUIPreviewImageAtt *att = [_previewImageAtts objectAtIndex:_viewBrowser.currentIndex];
    return att.image;
}

- (void)didShowImageAtIndex:(NSUInteger)index andIsOriginalImage:(BOOL)original
{

}

- (void)didScrollToNewImageAtIndex:(NSUInteger)newIndex
{

}

@end

#pragma mark --
#pragma mark -- ZoomPresentPreviewImageViewController

@interface ZoomInAnimation : NSObject<UIViewControllerAnimatedTransitioning>

@end

@interface ZoomOutAnimation : NSObject<UIViewControllerAnimatedTransitioning>

@end

@interface XUIPreviewImageViewController (ZoomPresentPreviewImageViewControllerInternal)<UIViewControllerTransitioningDelegate>

@end

@implementation XUIPreviewImageViewController (ZoomPresentPreviewImageViewController)

//-(void)setImageContainViews:(NSArray*)imageContainViews
//{
//    [self setAssociatedRetainNonatomicValue:imageContainViews withKey:"imageContainViews"];
//}
//
//-(NSArray*)imageContainViews
//{
//    return [self associatedValueForKey:"imageContainViews"];
//}

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
    return [ZoomInAnimation new];
}

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
    return [ZoomOutAnimation new];
}

- (void)zoomPresentPreviewImageViewController:(NSArray*)imageContainViews
{
    _presentType = XUIPreviewImageViewControllerPresentTypeZoom;
    
    self.imageContainViews = [imageContainViews mutableCopy];
    
    self.transitioningDelegate = self;
    
    [self presentViewControllerWithAnimated:YES completion:^
    {
        [self hiddenStatusBar:YES];
        
        [self rotationInterfaceOrientation:NO];
    }];
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"

-(void)zoomDismissPreviewImageView:(BOOL)animated
{
    [self hiddenStatusBar:NO];
    
    [[UIViewController currentRootViewController] dismissViewControllerAnimated:YES completion:NULL];
}

#pragma clang diagnostic pop

- (void)removeImageContainViewAtIndex:(NSUInteger)index
{
    [_imageContainViews removeObjectAtIndex:index];
}

@end

@implementation ZoomInAnimation

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
    return 0.25;
}

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
    XUIPreviewImageViewController *toVcl = (XUIPreviewImageViewController*)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    UIView *containerView = [transitionContext containerView];
    [containerView addSubview:toVcl.view];
 
    NSArray *imageContainViews = toVcl.imageContainViews;
    
    toVcl.view.backgroundColor = [UIColor clearColor];
    
    UIView *imageContainView = (UIView*)imageContainViews[[toVcl currentIndex]];
    CGRect ff = [containerView convertRect:imageContainView.frame fromView:imageContainView.superview];
    
    NSArray *ctrls = toVcl.view.subviews;
    CGAffineTransform oft = toVcl.view.transform;
    CGFloat mw = 1;
    
    if(ff.size.width >= ff.size.height)
    {
        mw = ff.size.width / containerView.width;
    }
    else
    {
        CGFloat mt = ff.size.width / containerView.width;
        if( mt * ff.size.height > containerView.height)
            mw = ff.size.height / containerView.height;
        else
            mw = mt;
    }
    
    toVcl.view.transform = CGAffineTransformMakeScale(mw, mw);
    
    CGFloat dh = (toVcl.view.height - ff.size.height)/2;
    toVcl.view.left = ff.origin.x;
    toVcl.view.top = ff.origin.y - dh;
    
    for(UIView *view in ctrls)
    {
        if([view isKindOfClass:[XUIPreviewImageViewInternal class]] == NO)
           [view removeFromSuperview];
    }
    
    containerView.userInteractionEnabled = NO;
    
    [UIView animateWithDuration:0.25 animations:^
    {
         toVcl.view.transform = oft;
         toVcl.view.origin = CGPointMake(0, 0);
    } completion:^(BOOL finished)
    {
        for(UIView *view in ctrls)
        {
            [toVcl.view addSubview:view];
        }
        [UIView animateWithDuration:0.25 animations:^
        {
             toVcl.view.backgroundColor = [UIColor blackColor];
        } completion:^(BOOL finished)
        {
            [transitionContext completeTransition:YES];

            containerView.userInteractionEnabled = YES;
        }];
    }];
}

@end

@implementation ZoomOutAnimation

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
    return 0.25;
}

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
    XUIPreviewImageViewController *toVcl = (XUIPreviewImageViewController*)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    
    UIView *containerView = [transitionContext containerView];
    
    containerView.backgroundColor = [UIColor clearColor];
    
    UIView *snapshotView = [[UIViewController currentRootViewController].view snapshotViewAfterScreenUpdates:YES];
    
    [containerView insertSubview:snapshotView atIndex:0];
    
    //如果不替换，ff的坐标会乱，原因不明
    containerView = [UIViewController currentRootViewController].view;
    
    NSArray *imageContainViews = toVcl.imageContainViews;
    
    if(imageContainViews.count <= 0)
    {
        containerView.userInteractionEnabled = NO;
        
        [UIView animateWithDuration:0.25 animations:^
        {
            toVcl.view.backgroundColor = [UIColor clearColor];
        } completion:^(BOOL finished)
        {
            [transitionContext completeTransition:YES];
            
            containerView.userInteractionEnabled = YES;
        }];
        
        return;
    }
    
    UIView *imageContainView = (UIView*)imageContainViews[[toVcl currentIndex]];
    CGRect ff = [containerView convertRect:imageContainView.frame fromView:imageContainView.superview];
    
    NSArray *ctrls = toVcl.view.subviews;
    CGFloat mw = 1;
    if(ff.size.width >= ff.size.height)
    {
        mw = ff.size.width / containerView.width;
    }
    else
    {
        CGFloat mt = ff.size.width / containerView.width;
        if( mt * ff.size.height > containerView.height)
            mw = ff.size.height / containerView.height;
        else
            mw = mt;
    }
    
    for(UIView *view in ctrls)
    {
        if([view isKindOfClass:[XUIPreviewImageViewInternal class]] == NO)
            [view removeFromSuperview];
    }
    
    containerView.userInteractionEnabled = NO;
    
    [UIView animateWithDuration:0.25 animations:^
    {
        toVcl.view.backgroundColor = [UIColor clearColor];
    } completion:^(BOOL finished)
    {
        [UIView animateWithDuration:0.25 animations:^
        {
            toVcl.view.transform = CGAffineTransformMakeScale(mw, mw);
            toVcl.view.origin = CGPointMake(ff.origin.x,ff.origin.y - (toVcl.view.height - ff.size.height)/2);
        } completion:^(BOOL finished)
        {
            [transitionContext completeTransition:YES];

            containerView.userInteractionEnabled = YES;
        }];
    }];
}

@end
